/*
 * @Author: lixu lixu@puchigames.com
 * @Date: 2025-06-16 10:17:13
 * @LastEditors: lixu lixu@puchigames.com
 * @LastEditTime: 2025-06-16 10:17:20
 * @FilePath: /go-helper/utils/convert.go
 * @Description: 类型转换工具函数，包含字符串、数字、布尔值等类型之间的相互转换功能
 */
package ixUtils

import (
	"encoding/json"
	"fmt"
	"strconv"
)

// DefaultValue 定义默认值
var DefaultValue = struct {
	Int    int
	Int64  int64
	Float  float64
	Bool   bool
	String string
}{
	Int:    0,
	Int64:  0,
	Float:  0.0,
	Bool:   false,
	String: "",
}

// ToInt 将任意类型转换为int类型
func ToInt(v interface{}) (int, error) {
	switch v := v.(type) {
	case int:
		return v, nil
	case int64:
		return int(v), nil
	case float64:
		return int(v), nil
	case string:
		return strconv.Atoi(v)
	case bool:
		if v {
			return 1, nil
		}
		return 0, nil
	default:
		return DefaultValue.Int, fmt.Errorf("unsupported type: %T", v)
	}
}

// MustInt 将任意类型转换为int类型，转换失败返回默认值
func MustInt(v interface{}) int {
	val, err := ToInt(v)
	if err != nil {
		return DefaultValue.Int
	}
	return val
}

// ToInt64 将任意类型转换为int64类型
func ToInt64(v interface{}) (int64, error) {
	switch v := v.(type) {
	case int:
		return int64(v), nil
	case int64:
		return v, nil
	case float64:
		return int64(v), nil
	case string:
		return strconv.ParseInt(v, 10, 64)
	case bool:
		if v {
			return 1, nil
		}
		return 0, nil
	default:
		return DefaultValue.Int64, fmt.Errorf("unsupported type: %T", v)
	}
}

// MustInt64 将任意类型转换为int64类型，转换失败返回默认值
func MustInt64(v interface{}) int64 {
	val, err := ToInt64(v)
	if err != nil {
		return DefaultValue.Int64
	}
	return val
}

// ToFloat 将任意类型转换为float64类型
func ToFloat(v interface{}) (float64, error) {
	switch v := v.(type) {
	case int:
		return float64(v), nil
	case int64:
		return float64(v), nil
	case float64:
		return v, nil
	case string:
		return strconv.ParseFloat(v, 64)
	case bool:
		if v {
			return 1, nil
		}
		return 0, nil
	default:
		return DefaultValue.Float, fmt.Errorf("unsupported type: %T", v)
	}
}

// MustFloat 将任意类型转换为float64类型，转换失败返回默认值
func MustFloat(v interface{}) float64 {
	val, err := ToFloat(v)
	if err != nil {
		return DefaultValue.Float
	}
	return val
}

// ToBool 将任意类型转换为bool类型
func ToBool(v interface{}) (bool, error) {
	switch v := v.(type) {
	case bool:
		return v, nil
	case int:
		return v != 0, nil
	case int64:
		return v != 0, nil
	case float64:
		return v != 0, nil
	case string:
		return strconv.ParseBool(v)
	default:
		return DefaultValue.Bool, fmt.Errorf("unsupported type: %T", v)
	}
}

// MustBool 将任意类型转换为bool类型，转换失败返回默认值
func MustBool(v interface{}) bool {
	val, err := ToBool(v)
	if err != nil {
		return DefaultValue.Bool
	}
	return val
}

// ToStr 将任意类型转换为字符串
func ToStr(v interface{}) string {
	if v == nil {
		return DefaultValue.String
	}

	switch v := v.(type) {
	case string:
		return v
	case int:
		return strconv.Itoa(v)
	case int64:
		return strconv.FormatInt(v, 10)
	case float64:
		return strconv.FormatFloat(v, 'f', -1, 64)
	case bool:
		return strconv.FormatBool(v)
	default:
		bytes, err := json.Marshal(v)
		if err != nil {
			return fmt.Sprintf("%v", v)
		}
		return string(bytes)
	}
}

// ToType 将任意类型转换为指定类型
func ToType(v interface{}, targetType string) (interface{}, error) {
	switch targetType {
	case "int":
		return ToInt(v)
	case "int64":
		return ToInt64(v)
	case "float64":
		return ToFloat(v)
	case "bool":
		return ToBool(v)
	case "string":
		return ToStr(v), nil
	default:
		return nil, fmt.Errorf("unsupported target type: %s", targetType)
	}
}

// MustType 将任意类型转换为指定类型，转换失败返回默认值
func MustType(v interface{}, targetType string) interface{} {
	val, err := ToType(v, targetType)
	if err != nil {
		switch targetType {
		case "int":
			return DefaultValue.Int
		case "int64":
			return DefaultValue.Int64
		case "float64":
			return DefaultValue.Float
		case "bool":
			return DefaultValue.Bool
		case "string":
			return DefaultValue.String
		default:
			return nil
		}
	}
	return val
}

// IsNil 检查值是否为nil
func IsNil(v interface{}) bool {
	return v == nil
}

// IsEmpty 检查值是否为空（nil、空字符串、0、false等）
func IsEmpty(v interface{}) bool {
	if v == nil {
		return true
	}

	switch v := v.(type) {
	case string:
		return v == ""
	case int:
		return v == 0
	case int64:
		return v == 0
	case float64:
		return v == 0
	case bool:
		return !v
	default:
		return false
	}
}
